﻿namespace ScrumLite.Services.Tests
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Rhino.Mocks;
    using ScrumLite.Services.Contracts;
    using ScrumLite.Data;
    using System.Collections.ObjectModel;

    [TestClass]
    public class LinqRolesServiceFixture
    {
        MockRepository mocks;

        [TestInitialize]
        public void Initialize()
        {
            this.mocks = new MockRepository();
        }

        [TestMethod]
        public void ShouldGetProjectRole()
        {
            ScrumLite.Data.IRoleStore store = this.mocks.DynamicMock<ScrumLite.Data.IRoleStore>();

            ScrumLite.Data.Role role = new ScrumLite.Data.Role { id = Guid.NewGuid(), name = "Developer Sr." };

            Expect.Call(store.GetRole(role.id))
                .Return(role)
                .Callback(new Func<Guid, bool>(g => { return true; }));
            mocks.ReplayAll();

            LinqRolesService service = new LinqRolesService(store);

            ScrumLite.Services.Contracts.ProjectRole actual = service.GetProjectRole(role.id.ToString());

            Assert.AreEqual(role.id, actual.Id);
            Assert.AreEqual(role.name, actual.Name);
        }

        [TestMethod]
        public void ShouldGetProjectRoles()
        {
            ScrumLite.Data.IRoleStore store = this.mocks.DynamicMock<ScrumLite.Data.IRoleStore>();

            ScrumLite.Data.Project project = new ScrumLite.Data.Project { id = Guid.NewGuid(), name = "ScrumLite" };
            ScrumLite.Data.Role role1 = new ScrumLite.Data.Role { id = Guid.NewGuid(), name = "Developer Sr." };
            ScrumLite.Data.Role role2 = new ScrumLite.Data.Role { id = Guid.NewGuid(), name = "Developer Jr." };
            ScrumLite.Data.ProjectRole projectRole1 = new ScrumLite.Data.ProjectRole { fk_project = project.id, fk_role = role1.id };
            ScrumLite.Data.ProjectRole projectRole2 = new ScrumLite.Data.ProjectRole { fk_project = project.id, fk_role = role2.id };

            role1.ProjectRoles.Add(projectRole1);
            role1.ProjectRoles.Add(projectRole2);

            List<ScrumLite.Data.Role> expected = new List<ScrumLite.Data.Role>();

            expected.Add(role1);
            expected.Add(role2);

            Expect.Call(store.GetProjectRoles(project.id))
                .Return(expected.ToArray())
                .Callback(new Func<Guid, bool>(g => { return true; }));
            mocks.ReplayAll();

            LinqRolesService service = new LinqRolesService(store);

            Collection<ScrumLite.Services.Contracts.ProjectRole> roles = service.GetProjectRoles(project.id.ToString());

            Assert.AreEqual(roles.Count(), 2);
            Assert.AreEqual(role1.name, roles[0].Name);
            Assert.AreEqual(role2.name, roles[1].Name);
        }

        [TestMethod]
        public void ShouldGetRolesAbilities()
        {
            ScrumLite.Data.IRoleStore store = this.mocks.DynamicMock<ScrumLite.Data.IRoleStore>();

            ScrumLite.Data.Project project = new ScrumLite.Data.Project { id = Guid.NewGuid(), name = "ScrumLite" };
            ScrumLite.Data.Role role = new ScrumLite.Data.Role { id = Guid.NewGuid(), name = "Developer Sr." };
            ScrumLite.Data.Ability ability1 = new ScrumLite.Data.Ability { id = Guid.NewGuid(), name = "C#" };
            ScrumLite.Data.Ability ability2 = new ScrumLite.Data.Ability { id = Guid.NewGuid(), name = "ASP.Net" };
            ScrumLite.Data.RoleAbility roleAbility1 = new ScrumLite.Data.RoleAbility { fk_role = role.id, fk_ability = ability1.id };

            ability1.RoleAbilities.Add(roleAbility1);

            List<ScrumLite.Data.Ability> expected = new List<ScrumLite.Data.Ability>();

            expected.Add(ability1);
            expected.Add(ability2);

            Expect.Call(store.GetRoleAbilities(project.id, role.id))
                .Return(expected.ToArray())
                .Callback(new Func<Guid, Guid,  bool>((g, w) => { return true; }));
            mocks.ReplayAll();

            LinqRolesService service = new LinqRolesService(store);

            Collection<ScrumLite.Services.Contracts.Ability> abilities = service.GetAbilities(project.id.ToString(), role.id.ToString());

            Assert.AreEqual(abilities.Count(), 2);
            Assert.AreEqual(ability1.name, abilities[0].Name);
            Assert.AreEqual(ability2.name, abilities[1].Name);
        }


        [TestMethod]
        public void ShouldAddRole()
        {
            ScrumLite.Data.IRoleStore store = this.mocks.DynamicMock<ScrumLite.Data.IRoleStore>();

            ScrumLite.Data.Project project = new ScrumLite.Data.Project { id = Guid.NewGuid(), name = "ScrumLite" };

            bool called = false;
            string addedrole = null;

            Expect.Call(() => store.AddRoleToProject(project.id,"Tester", null))
                .Callback(new Func<Guid, string, string[], bool>((g, r, a) => { called = true; addedrole = r;  return true; }));
            mocks.ReplayAll();

            LinqRolesService service = new LinqRolesService(store);

            service.AddRoleToProject(project.id.ToString(), "Tester", null);

            Assert.IsTrue(called);
            Assert.AreEqual("Tester", addedrole);
        }
    }
}
